/**
 * Copyright 2010 Creative Works, Inc.
 * Creative Works licenses this file to you under the Apache License, version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *    http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.sendvox.freswitch.event.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.sendvox.freswitch.inbound.impl.ResponseCallbacks;
import org.sendvox.freswitch.util.Arguments;

public class RawMessage {

	private static final Logger logger = Logger.getLogger(RawMessage.class
			.getName());

	private final Map<ResponseCallbacks, String> headers = new HashMap<ResponseCallbacks, String>();

	private Map<Header, String> eventBodyMap = new HashMap<Header, String>();

	private final List<String> bodyList = new ArrayList<String>();

	private final static String KEY_VALUE_SEPARATOR = ":";
	private final static String ERROR = "-ERR";
	private final static String OK = "+OK";
	private final static String DISCONNECTED = "Disconnected";
	private final static String GREETINGS = "See you at ClueCon!";
	private final static String HTTP = "http:";

	private Integer contentLength = null;

	public boolean hasContentLength() {
		return headers.containsKey(ResponseCallbacks.CONTENT_LENGTH);
	}

	public Integer getContentLength() {
		if (contentLength != null) {
			return contentLength;
		}
		if (hasContentLength()) {
			contentLength = Integer.valueOf(headers
					.get(ResponseCallbacks.CONTENT_LENGTH));
		}
		return contentLength;
	}

	public String getContentType() {
		return headers.get(ResponseCallbacks.CONTENT_TYPE);
	}

	public Map<ResponseCallbacks, String> getHeaders() {
		return headers;
	}

	public boolean hasHeader(ResponseCallbacks name) {
		return headers.containsKey(name);
	}

	public String getHeader(ResponseCallbacks name) {
		return headers.get(name);
	}

	public Map<Header, String> getEventBodyMap() {
		return eventBodyMap;
	}

	public String getEventBody(Header name) {
		return getEventBodyMap().get(name);
	}

	public boolean hasEventBody(Header name) {
		if (bodyList.isEmpty())
			return false;
		return getEventBodyMap().containsKey(name);
	}

	public List<String> getBodyLines() {
		return bodyList;
	}

	public void addHeader(ResponseCallbacks name, String value) {
		logger.log(Level.FINE, "adding header [" + name + "] [" + value + "]");
		headers.put(name, value);
	}

	public void addBodyLine(String bodyLine) {
		String key = null, value = null;
		if (bodyLine == null) {
			return;
		} else if (bodyLine.contains(KEY_VALUE_SEPARATOR)
				&& !bodyLine.contains(HTTP)) {
			key = bodyLine.split(":")[0];
			value = bodyLine.split(":")[1];
		} else if (bodyLine.contains(ERROR)) {
			key = ERROR;
			value = bodyLine;
		} else if (bodyLine.contains(OK)) {
			key = OK;
			value = bodyLine;
		} else if (bodyLine.contains(DISCONNECTED)) {
			key = DISCONNECTED;
			value = bodyLine;
		} else if (bodyLine.contains(GREETINGS)) {
			key = GREETINGS;
			value = bodyLine;
		} else {
			logger.log(Level.INFO, "Body line: " + bodyLine);
		}
		Arguments.INSTANCE.validate(key, value).isNotNull().isNotEmpty();
		Header header = Header.fromLiteral(key);
		if (header == null) {
			throw new IllegalStateException("Unhandled ESL header [" + key
					+ ']');
		}
		eventBodyMap.put(Header.fromLiteral(key), value);
		bodyList.add(bodyLine);
	}

	@Override
	public String toString() {
		return " [headers=" + headers + ", body=" + bodyList
				+ ", contentLength=" + contentLength + "]";
	}

}
